/*
	Copyright (c) 2011 Canadensys
*/
package net.canadensys.dataportal.vascan.config;

import net.canadensys.dataportal.scientificname.TaxonRankEnum;
import net.canadensys.dataportal.vascan.config.impl.InstallationConfig;

/**
 * This class keeps the config related to the application itself.
 *
 */
public class ApplicationConfig {
	
	private static final InstallationConfig INSTALLATION_CONFIG_INSTANCE = InstallationConfig.getInstance();
	
	/*
	 * LUCENE
	 */
	public static final String		LUCENE_INDEX = "taxon";
	public static final String		LUCENE_NAMEBAG = "namebag";
	public static final int			LUCENE_MAX_RESULTS = 10;
	
	/*
	 * LANGUAGES
	 */
	public static final String		LANGUAGE_FR = "fr";
	public static final String		LANGUAGE_EN = "en";
	
	/*
	 * HABITUS
	 */
	public static final	int			HABITUS_NONE = 1;
	public static final	int			HABITUS_HERB = 2;
	public static final	int			HABITUS_SHRUB = 3;
	public static final	int			HABITUS_TREE = 4;
	public static final	int			HABITUS_VINE = 5;
	public static final String		LABEL_HABITUS_NONE = "none";
	public static final String		LABEL_HABITUS_HERB = "herb";
	public static final String		LABEL_HABITUS_SHRUB = "shrub";
	public static final String		LABEL_HABITUS_TREE = "tree";
	public static final String		LABEL_HABITUS_VINE = "vine";
	
	/*
	 * DISTRIBUTIONS
	 */
	public static final int			DISTRIBUTION_NATIVE = 1;
	public static final int			DISTRIBUTION_INTRODUCED = 2;
	public static final int			DISTRIBUTION_EPHEMERE = 3;
	public static final int			DISTRIBUTION_EXTIRPATED = 4;
	public static final int			DISTRIBUTION_EXCLUDED = 5;
	public static final int			DISTRIBUTION_DOUBTFUL = 6;
	public static final int			DISTRIBUTION_ABSENT = 7;
	public static final String		LABEL_DISTRIBUTION_NATIVE = "native";
	public static final String		LABEL_DISTRIBUTION_INTRODUCED = "introduced";
	public static final String		LABEL_DISTRIBUTION_EPHEMERAL = "ephemeral";
	public static final String		LABEL_DISTRIBUTION_EXTIRPATED = "extirpated";
	public static final String		LABEL_DISTRIBUTION_EXCLUDED = "excluded";
	public static final String		LABEL_DISTRIBUTION_ABSENT = "absent";
	public static final String		LABEL_DISTRIBUTION_DOUBTFUL = "doubtful";
	
	public static final String		COLOR_DISTRIBUTION_DEFAULT = "#d3d3d3";
	public static final String		COLOR_DISTRIBUTION_NATIVE = "#77bb2b";
	public static final String		COLOR_DISTRIBUTION_INTRODUCED = "#e98c1f";
	public static final String		COLOR_DISTRIBUTION_EPHEMERAL = "#f2df0d";
	public static final String		COLOR_DISTRIBUTION_EXTIRPATED = "#000000";
	public static final String		COLOR_DISTRIBUTION_EXCLUDED = "#6e6e6e";
	public static final String		COLOR_DISTRIBUTION_ABSENT = "#d3d3d3";
	public static final String		COLOR_DISTRIBUTION_DOUBTFUL = "#afafaf";
	
	/*
	 * PROVINCES
	 */
	public static final int			PROVINCE_AB = 1;
	public static final int			PROVINCE_BC = 2;
	public static final int			PROVINCE_GL = 3;
	public static final int			PROVINCE_NLL = 4;
	public static final int			PROVINCE_MB = 5;
	public static final int			PROVINCE_NB = 6;
	public static final int			PROVINCE_NLN = 7;
	public static final int			PROVINCE_NT = 8;
	public static final int			PROVINCE_NS = 9;
	public static final int			PROVINCE_NU = 10;
	public static final int			PROVINCE_ON = 11;
	public static final int			PROVINCE_PE = 12;
	public static final int			PROVINCE_QC = 13;
	public static final int			PROVINCE_PM = 14;
	public static final int			PROVINCE_SK = 15;
	public static final int			PROVINCE_YT = 16;
	
	//includes Greenland and St-Pierre Miquelon
	public static final String ALL_PROVINCES[] = {"AB","BC","GL","NL_N","NL_L","MB","NB","NT","NS","NU","ON","PE","QC","PM","SK","YT"};
	public static final String CANADA_PROVINCES[] = {"AB","BC","NL_N","NL_L","MB","NB","NT","NS","NU","ON","PE","QC","SK","YT"};

	/*
	 * STATUS
	 */
	public static final int			STATUS_ACCEPTED = 1;
	public static final int			STATUS_SYNONYM = 2;
	public static final String		LABEL_STATUS_ACCEPTED = "accepted";
	public static final String		LABEL_STATUS_SYNONYM = "synonym";
	
	/*
	 * RANK VALUES
	 */
	public static final int			RANK_ROOT = 0;
	public static final int			RANK_CLASS = 1;
	public static final int			RANK_SUBCLASS = 2;
	public static final int			RANK_SUPERORDER = 3;
	public static final int			RANK_ORDER = 4;
	public static final int			RANK_FAMILY = 5;
	public static final int			RANK_SUBFAMILY = 6;
	public static final int			RANK_TRIBE = 7;
	public static final int			RANK_SUBTRIBE = 8;
	public static final int			RANK_GENUS = 9;
	public static final int			RANK_SUBGENUS = 10;
	public static final int			RANK_SECTION = 11;
	public static final int			RANK_SUBSECTION = 12;
	public static final int			RANK_SERIES = 13;
	public static final int			RANK_SPECIES = 14;
	public static final int			RANK_SUBSPECIES = 15;
	public static final int			RANK_VARIETY = 16;
	public static final int			RANK_UNDEFINED = 17;
	public static final String		LABEL_RANK_ROOT = "root";
	public static final String		LABEL_RANK_CLASS = "class";
	public static final String		LABEL_RANK_SUBCLASS = "subclass";
	public static final String		LABEL_RANK_SUPERORDER = "superorder";
	public static final String		LABEL_RANK_ORDER = "order";
	public static final String		LABEL_RANK_FAMILY = "family";
	public static final String		LABEL_RANK_SUBFAMILY = "subfamily";
	public static final String		LABEL_RANK_TRIBE = "tribe";
	public static final String		LABEL_RANK_SUBTRIBE = "subtribe";
	public static final String		LABEL_RANK_GENUS = "genus";
	public static final String		LABEL_RANK_SUBGENUS = "subgenus";
	public static final String		LABEL_RANK_SECTION = "section";
	public static final String		LABEL_RANK_SUBSECTION = "subsection";
	public static final String		LABEL_RANK_SERIES = "series";
	public static final String		LABEL_RANK_SPECIES = "species";
	public static final String		LABEL_RANK_SUBSPECIES = "subspecies";
	public static final String		LABEL_RANK_VARIETY = "variety";
	public static final String		LABEL_RANK_UNDEFINED = "undefined";
	
	//Root of all taxon : 73 = class = Equisetopsida
	public static final int ROOT_TAXON_ID = 73;
	public static final String CONFIG_KEY_LAST_PUBLICATION_DATE = "last_publication_date";
	
	/*
	 * DARWIN CORE ARCHIVE FILES
	 */
	public static final String		DARWIN_CORE_FILE_META = "meta.xml";
	//private constant, it's a relative path. Use getMetaXMLFilePath()
	private static final String		DARWIN_CORE_FILE_META_REL_PATH = "/downloads/" + DARWIN_CORE_FILE_META;
	public static final String		DARWIN_CORE_FILE_TAXON = "taxon.txt";
	public static final String		DARWIN_CORE_FILE_DISTRIBUTION = "distribution.txt";
	public static final String		DARWIN_CORE_FILE_VERNACULAR = "vernacularnames.txt";
	public static final String		DARWIN_CORE_FILE_HABITUS = "habit.txt";
	public static final String		DARWIN_CORE_FILE_COMPLETE_ARCHIVE = "vascan.zip";
	
	public static final String		DARWIN_CORE_FILE_ARCHIVE_PREFIX = "DWC-";
	public static final String		DARWIN_CORE_FILE_ARCHIVE_EXT = ".zip";
	public static final String		DARWIN_CORE_TEMP_ARCHIVE_EXT = ".tmp";
	
	//private constant, Use getGeneratedImageURL()
	private static final String 	GENERATED_IMG_URL = "image?q=";
	public static final String 		DOWNLOAD_GENERATED_IMG_URL = "&a=download";
	
	/*
	 * CSV FILES
	 */
	public static final String		CSV_FILE_PREFIX = "TXT-";
	public static final String		CSV_FILE_EXT = ".txt";
	
	/*
	 * SVG FILES
	 */
	public static final String		SVG_FILE_PREFIX = "distribution";
	public static final String		SVG_FILE_EXT = ".svg";
	public static final String		PNG_FILE_EXT = ".png";
	
	/*
	 * XML sitemap
	 */
	private static final String		SITEMAP_URL_TAXON = "taxon/";
	private static final String		SITEMAP_URL_VERNACULAR = "vernacular/";
	
	public static final String		SITEMAP_LANG_PARAM_FR = "lang=fr";
	
	private static final String		SITEMAP_TAXON_EN = "taxon_en.xml";
	private static final String		SITEMAP_VERNACULAR_EN = "vernacular_en.xml";
	private static final String		SITEMAP_TAXON_FR = "taxon_fr.xml";
	private static final String		SITEMAP_VERNACULAR_FR = "vernacular_fr.xml";

	private ApplicationConfig(){}//hide the constructor, this is a static class
	
	public static String getSiteMapURLTaxon(){
		return SITEMAP_URL_TAXON;
	}
	public static String getSiteMapURLVernacular(){
		return SITEMAP_URL_VERNACULAR;
	}
	
//  this is confusing
//	public static String getSiteMapRoot(){
//		return INSTALLATION_CONFIG_INSTANCE.get(InstallationConfig.INSTALLATION_DIR_KEY);
//	}
	
	public static String getTaxonSiteMapFileEN(){
		return INSTALLATION_CONFIG_INSTANCE.get(InstallationConfig.SITE_MAP_DIR_KEY) + SITEMAP_TAXON_EN;
	}
	public static String getTaxonSiteMapFileFR(){
		return INSTALLATION_CONFIG_INSTANCE.get(InstallationConfig.SITE_MAP_DIR_KEY) + SITEMAP_TAXON_FR;
	}
	
	public static String getVernacularSiteMapFileEN(){
		return INSTALLATION_CONFIG_INSTANCE.get(InstallationConfig.SITE_MAP_DIR_KEY) + SITEMAP_VERNACULAR_EN;
	}
	public static String getVernacularSiteMapFileFR(){
		return INSTALLATION_CONFIG_INSTANCE.get(InstallationConfig.SITE_MAP_DIR_KEY) + SITEMAP_VERNACULAR_FR;
	}
	
	/**
	 * meta.xml path relative to installation directory
	 * @return
	 */
	public static String getMetaXMLFilePath(){
		return INSTALLATION_CONFIG_INSTANCE.get(InstallationConfig.INSTALLATION_DIR_KEY) + DARWIN_CORE_FILE_META_REL_PATH;
	}
	
	public static String getGeneratedImageURL(){
		return INSTALLATION_CONFIG_INSTANCE.get(InstallationConfig.VASCAN_ROOT_URL_KEY) + GENERATED_IMG_URL;
	}
	
	public static String[] getDistributionLabelArray(){
		return new String[]{
			LABEL_DISTRIBUTION_NATIVE,
			LABEL_DISTRIBUTION_INTRODUCED,
			LABEL_DISTRIBUTION_EPHEMERAL,
			LABEL_DISTRIBUTION_EXTIRPATED,
			LABEL_DISTRIBUTION_EXCLUDED,
			LABEL_DISTRIBUTION_ABSENT,
			LABEL_DISTRIBUTION_DOUBTFUL};
	}
	
	/**
	 * Return the ranks as String array from Class to Variety.
	 * @return the ranks from Class to Variety.
	 */
	public static String[] getRankLabelArray(){
		return new String[]{
			LABEL_RANK_CLASS,
    		LABEL_RANK_SUBCLASS,
    		LABEL_RANK_ORDER,
    		LABEL_RANK_SUPERORDER,
    		LABEL_RANK_FAMILY,
    		LABEL_RANK_SUBFAMILY,
    		LABEL_RANK_SUBTRIBE,
    		LABEL_RANK_TRIBE,
    		LABEL_RANK_GENUS,
    		LABEL_RANK_SUBGENUS,
    		LABEL_RANK_SECTION,
    		LABEL_RANK_SUBSECTION,
    		LABEL_RANK_SERIES,
    		LABEL_RANK_SPECIES,
    		LABEL_RANK_SUBSPECIES,
    		LABEL_RANK_VARIETY};
	}
	
	/**
	 * Converts the Vascan rankId into its corresponding TaxonRankEnum.
	 * @param rankId
	 * @return corresponding TaxonRankEnum or null if not match was found.
	 */
	public static TaxonRankEnum getRankAsEnum(int rankId){
		switch (rankId) {
			case RANK_CLASS:return TaxonRankEnum.CLASS;
			case RANK_SUBCLASS:return TaxonRankEnum.SUBCLASS;
			case RANK_SUPERORDER:return TaxonRankEnum.SUPERORDER;
			case RANK_ORDER:return TaxonRankEnum.ORDER;
			case RANK_FAMILY:return TaxonRankEnum.FAMILY;
			case RANK_SUBFAMILY:return TaxonRankEnum.SUBFAMILY;
			case RANK_TRIBE:return TaxonRankEnum.TRIBE;
			case RANK_SUBTRIBE:return TaxonRankEnum.SUBTRIBE;
			case RANK_GENUS:return TaxonRankEnum.GENUS;
			case RANK_SUBGENUS:return TaxonRankEnum.SUBGENUS;
			case RANK_SECTION:return TaxonRankEnum.SECTION;
			case RANK_SUBSECTION:return TaxonRankEnum.SUBSECTION;
			case RANK_SERIES:return TaxonRankEnum.SERIES;
			case RANK_SPECIES:return TaxonRankEnum.SPECIES;
			case RANK_SUBSPECIES:return TaxonRankEnum.SUBSPECIES;
			case RANK_VARIETY:return TaxonRankEnum.VARIETY;
		}
		return null;
	}
	/**
	 * Converts a TaxonRankEnum into its corresponding Vascan rankId.
	 * @param rankEnum
	 * @return corresponding rankId or -1 if not match was found.
	 */
	public static int getRankIdFromEnum(TaxonRankEnum rankEnum){
		switch (rankEnum) {
			case CLASS:return RANK_CLASS;
			case SUBCLASS:return RANK_SUBCLASS;
			case SUPERORDER:return RANK_SUPERORDER;
			case ORDER:return RANK_ORDER;
			case FAMILY:return RANK_FAMILY;
			case SUBFAMILY:return RANK_SUBFAMILY;
			case TRIBE:return RANK_TRIBE;
			case SUBTRIBE:return RANK_SUBTRIBE;
			case GENUS:return RANK_GENUS;
			case SUBGENUS:return RANK_SUBGENUS;
			case SECTION:return RANK_SECTION;
			case SUBSECTION:return RANK_SUBSECTION;
			case SERIES:return RANK_SERIES;
			case SPECIES:return RANK_SPECIES;
			case SUBSPECIES:return RANK_SUBSPECIES;
			case VARIETY:return RANK_VARIETY;
		}
		return -1;
	}

}
